module crc16
       #(
           parameter Initial = 16'h0000
       )
       (
           input wire clk,
           input wire rst_n,
           input wire clear,
           input wire din,
           input wire din_valid,
           output wire [15: 0] crc
       );

reg [15: 0] crc_reg;
assign crc = crc_reg;

wire xor_input = din ^ crc_reg[15];

always @(posedge clk) begin
    if (!rst_n) begin
        crc_reg <= Initial;
    end else begin
        if (clear) begin
            crc_reg <= Initial;
        end else begin
            if (din_valid) begin
                crc_reg <= {
                    crc_reg[14: 12], 
                    crc_reg[11] ^ xor_input, 
                    crc_reg[10: 5], 
                    crc_reg[4] ^ xor_input, 
                    crc_reg[3: 0], 
                    xor_input};
            end else ;
        end
    end
end

endmodule
